#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>

#define MAX 1024
#define ARGC 64
#define SEP " "

enum redir
{
    REDIR_INPUT = 0,
    REDIR_OUTPUT,
    REDIR_APPEND,
    REDIR_NONE
};

char *checkDir(char commandstr[], redir &redir_type)
{
    //1.检测commandstr内部是否有> >> <
    //2.如果有要根据> >> < 设置redir_type = ？
    //3.
}

int split(char *commandstr, char *argv[])
{
    assert(commandstr);
    assert(argv);

    argv[0] = strtok(commandstr, SEP);
    if (argv[0] == NULL)
        return -1;
    int i = 1;
    while (argv[i++] = strtok(NULL, SEP))
        ;
    // while (1)
    // {
    //     argv[i] = strtok(NULL, SEP);
    //     if (argv[i] == NULL)
    //         break;
    //     i++;
    // }
    return 0;
}

void debugPrint(char *argv[])
{
    int i = 0;
    for (i = 0; argv[i]; i++)
    {
        printf("%d : %s\n", i, argv[i]);
    }
}

void showEnv()
{
    extern char **environ;
    int i = 0;
    for (i = 0; environ[i]; i++)
        printf("%d : %s\n", i, environ[i]);
}

int main()
{

    int last_exit = 0;
    char myenv[32][256];
    int env_index = 0;

    while (1)
    {
        redir redir_type = REDIR_NONE;
        char commandstr[MAX] = {0};
        char *argv[ARGC] = {NULL};
        printf("[zhangsan@mymachine currpath]#");
        fflush(stdout);
        // cat Makefile > log.txt

        char *s = fgets(commandstr, sizeof(commandstr), stdin);
        assert(s);
        (void)s;
        commandstr[strlen(commandstr) - 1] = '\0';
        char *filename = checkDir(commandstr, &redir_type);

        int n = split(commandstr, argv);
        assert(n == 0);
        if (n != 0)
            continue;
        // debugPrint(argv);

        // 代码从这里拦截，就不执行后面的代码，因为cd命名是内建命令，重要的表现就是bash自己执行的命令
        if (strcmp(argv[0], "cd") == 0)
        {
            if (argv[1] != NULL)
                chdir(argv[1]);
            continue;
        }
        else if (strcmp(argv[0], "export") == 0)
        {
            if (argv[1] != NULL)
            {
                strcpy(myenv[env_index], argv[1]);
                putenv(myenv[env_index++]);
            }

            continue;
        }
        else if (strcmp(argv[0], "env") == 0)
        {
            showEnv();
            continue;
        }
        else if (strcmp(argv[0], "echo") == 0)
        {
            // echo $PATH
            const char *target_env = NULL;
            if (argv[1][0] == '$')
            {
                if (argv[1][1] == '?')
                {
                    printf("%d\n", last_exit);
                    continue;
                }
                else
                    target_env = getenv(argv[1] + 1);

                if (target_env != NULL)
                    printf("%s=%s\n", argv[1] + 1, target_env);
            }
            continue;
        }

        if (strcmp(argv[0], "ls") == 0)
        {
            int pos = 0;
            while (argv[pos] != NULL)
                pos++;
            argv[pos++] = (char *)"--color=auto";
            argv[pos] = NULL;
        }

        pid_t id = fork();
        assert(id >= 0);
        (void)id;
        if (id == 0)
        {
            if (filename)
            {
                // 1.存在文件的
                // 2.redir_type获取到
                // 3.dup2
            }

            // child

            execvp(argv[0], argv);
            exit(1);
        }
        int status = 0;
        pid_t ret = waitpid(id, &status, 0);
        if (ret > 0)
        {
            last_exit = WEXITSTATUS(status);
        }
        // printf("%s\n",commandstr);
    }
    return 0;
}